package gw.com.android.ui.me;

import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.AbsListView;
import android.widget.ExpandableListView;

/**
 * 允许第一个child有一定弹性的listView
 */
public class StretchyHeaderListView extends ExpandableListView {

    public StretchyHeaderListView(Context context) {
        this(context, null);
    }

    public StretchyHeaderListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StretchyHeaderListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                View childAt0 = getChildAt(0);
                boolean res = false;
                if (childAt0 instanceof StretchyLayout) {// 如果第一个显示的是header
                    Log.d("onScrollTag-getTop", "" + childAt0.getTop());
                    if (childAt0.getTop() == 0) {//并且header完整显示
                        // 那么就允许随着下拉手势动态改变header高度
                        res = true;
                    }
                }
                setIfAllowChangeHeightOfHeader(res);
            }
        });
    }

    private boolean ifAllowStretchy = true;//是否开启弹性特性

    public void setIfAllowStretchy(boolean ifAllowStretchy) {
        this.ifAllowStretchy = ifAllowStretchy;
    }

    private boolean ifAllowChangeHeightOfHeader = false;
    private float maxMultiple = 3f; // 最大拉伸的倍数
    float rawY;//可能随时变动的y绝对坐标
    int downY = 0;//只接收down时的Y绝对坐标
    int currentHeaderHeight;//可能会随时变动的header高度
    int oriHeaderHeight;// 原始高度
    private View headerView;//header对象
    private boolean ifInAnimator = false;// 是否正在执行动画,true表示正在执行回弹动画，false表示动画已完毕 // 回弹完成之前，不允许再拉
    private ValueAnimator resumeAnimator;

    private void setIfAllowChangeHeightOfHeader(boolean temp) {
        ifAllowChangeHeightOfHeader = temp;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        if (!ifAllowStretchy)
            return false;

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
//                downY = (int) ev.getRawY();
                //在这里测量出header的高度
                View childAt0 = getChildAt(0);
                if (childAt0 instanceof StretchyLayout) {
                    //获取高度.
                    headerView = childAt0;
                    currentHeaderHeight = childAt0.getMeasuredHeight();
                    if (oriHeaderHeight == 0)
                        setOriHeaderHeight(currentHeaderHeight);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float disY = ev.getRawY() - rawY;
                float realDisY = disY / 3;//只滑动它的1/3;
                currentHeaderHeight += realDisY;
                if (ifAllowChangeHeightOfHeader)//如果允许拉伸, 才进行事件处理;
                {
                    if (ifInAnimator)// 如果动画正在执行
                        cancelResumeHeight();//那就停止动画
                    changeHeaderHeight(currentHeaderHeight);// 再进行高度更改
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:// 在模拟器上发现诡异现象，瞬间下拉大段距离，有可能不触发up，也不触发CANCEL。。尼玛。。不按套路出牌！ 真机上尚未发现。
                resumeHeight();
                break;
        }
        rawY = ev.getRawY();

        return super.onTouchEvent(ev);
    }

    public void setOriHeaderHeight(int height) {
        oriHeaderHeight = height;
    }


    /**
     * 改变本体的高度
     *
     * @param height
     */
    private void changeHeaderHeight(int height) {
        int maxHeight = (int) (oriHeaderHeight * maxMultiple);// 最大拉伸距离,
        if (height > maxHeight) {// 设置边界
            height = maxHeight;
        } else if (height < oriHeaderHeight)
            height = oriHeaderHeight;

        if (null != headerView) {
            headerView.getLayoutParams().height = height;
            headerView.requestLayout();
        } else {
            String s = "出现了headerView是空的情况，~~~！！@#@！";
            Log.d("changeHeaderHeight", s);
        }
    }

    /**
     * 使用动画回弹布局高度, 将当前高度 慢慢变为 原始高度
     */
    private void resumeHeight() {
        Log.d("changeHeaderHeight", "松开手的时候:currentHeaderHeight=" + currentHeaderHeight + ";oriHeaderHeight=" + oriHeaderHeight);
        cancelResumeHeight();
        resumeAnimator = ValueAnimator.ofInt(currentHeaderHeight, oriHeaderHeight);
        resumeAnimator.setInterpolator(new LinearInterpolator());
        resumeAnimator.setDuration(500);
        resumeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float current = (int) animation.getAnimatedValue();
                changeHeaderHeight((int) current);
                if (current == oriHeaderHeight) {
                    ifInAnimator = false;
                    currentHeaderHeight = oriHeaderHeight;// 动画执行完了之后，将当前高度设置为原始高度
                }
            }
        });
        resumeAnimator.start();
        ifInAnimator = true;
    }

    private void cancelResumeHeight() {
        if (resumeAnimator != null)
            resumeAnimator.cancel();
        ifInAnimator = false;
    }


}

